#include <string.h>
#include <iostream>
using std::cout;
using std::endl;

class Base
{
public:
    Base(const char * pstr)
    : _pbase(new char[strlen(pstr) + 1]())
    {
        strcpy(_pbase,pstr);
        cout << "Base(const char *)" << endl;
    }

    Base(const Base & rhs)
    : _pbase(new char[strlen(rhs._pbase) + 1]())
    {
        strcpy(_pbase,rhs._pbase);
        cout << "Base(const Base &)" << endl;
    }

    Base& operator=(const Base& rhs){
        if(this != &rhs){
            delete [] _pbase;
            _pbase = new char[strlen(rhs._pbase)]();
            strcpy(_pbase,rhs._pbase);
            cout << "Base& operator=(const Base &)" << endl;
        }
        return *this;
    }

    ~Base(){
        cout << "~Base()" << endl;
        if(_pbase){
            delete [] _pbase;
            _pbase = nullptr;
        }
    }

    void print() const{
        cout << "Base::_pbase:" << _pbase << endl;
    }
protected:
    char * _pbase;
};

class Derived
: public Base
{
public:
    Derived(const char * pstr,const char * pderived)
    : Base(pstr)
    , _pderived(new char[strlen(pderived) + 1]())
    {
        strcpy(_pderived,pderived);
        cout << "Derived(const char *)" << endl;
    }

    void display() const{
        print();
        cout << "Derived::_pderived:" << _pderived << endl;
        cout << "Derived::_derived:" << _derived << endl;
    }


    Derived(const Derived & rhs)
    : Base(rhs)//显式调用基类的拷贝构造
    , _pderived(new char[strlen(rhs._pderived) + 1]())
    {
        strcpy(_pderived, rhs._pderived);
        cout << "Derived(const Derived &)" << endl;
    }

    Derived & operator=(const Derived & rhs){
        cout << "Derived & operator=(const Derived &)" << endl;
        if(this != &rhs){
            //显式调用基类的赋值运算符函数
            Base::operator=(rhs);//关键
            delete [] _pderived;
            _pderived = new char[strlen(rhs._pderived) + 1]();
            strcpy(_pderived,rhs._pderived);
            _derived = rhs._derived;
        }
        return *this;
    }

    ~Derived() { 
        cout << "~Derived()" << endl;
        if(_pderived){
            delete [] _pderived;
            _pderived = nullptr;
        }
    }
private:
    char * _pderived;
    long _derived = 10;
};


void test0(){
    Derived d1("hello","world");
    Derived d2 = d1;
    d2.display();

    Derived d3("beijing","shanghai");
    cout << endl;
    d2 = d3;
    d2.display();

}

int main(void){
    test0();
    return 0;
}
